/*------------------------------------------------------------------------------
ssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssss
--------------------------------------------------------------------------------
This program was written for Afflatus Techtronics - Resource section.

Project                 : USART communication on PIC18Fxxx
File                    : usart.c
Code type               : Code Module

Controller              : PIC18Fxxx
XTAL frequency          : 8MHz [Internal]
Compiler and IDE        : MCC18 with MPLab IDE

Author                  : Ashwin Vijayakumar
Current Occupation      : Computer Engineering Graduate student @ WMU, Kalamazoo
                          , Michigan

Start Date              : Jan-15-2010
Validation Date         : Jan-15-2010

--------------------------------------------------------------------------------
ssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssss
------------------------------------------------------------------------------*/

#include <p18cxxx.h>
#include <string.h>

#include "McalUart.h"
#include "McalIsr.h"
#include "PalDs1629.h"
#include "time.h"

// -----------------------------------------------------------------------------
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~// USART Initialization ~~~~~~~~~~~~~~~~
// -----------------------------------------------------------------------------

void McalUart_Init(void)
{
  /* Transmit enable */
  TXSTAbits.TXEN = 1;

  /* Continuous receive enable */
  RCSTAbits.CREN = 1;

  /* Set RX pin as input */
  TRISCbits.TRISC7 = 1;

  /* Set TX pin as output */
  TRISCbits.TRISC6 = 0;
  //TXSTAbits.BRGH = 1;

  /* Baud rate [9600 @ 8MHz] */
  SPBRG = 12;

  /* Serial port enable */
  RCSTAbits.SPEN = 1;

  RCONbits.IPEN = 1;  /* Enable interrupt priority */
  IPR1bits.RCIP = 1;  /* Make receive interrupt high priority */
  PIE1bits.RCIE = 1;   // Enable Rx interrupts
  IPR1bits.TXIP = 1;   // USART Tx on high priority interrupt
  PIE1bits.TXIE = 0;   // Disable Tx interrupts until we need to send

  INTCONbits.GIEH = 1;  /* Enable all high priority interrupts */
}

// -----------------------------------------------------------------------------
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~// USART Initialization ~~~~~~~~~~~~~~~~
// -----------------------------------------------------------------------------

// -----------------------------------------------------------------------------
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~// USART Transmit Routine ~~~~~~~~~~~~~~~
// -----------------------------------------------------------------------------

// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~// Send a character ~~~~~~~~~~~~~~~~~~~~

void McalUart_Putc( char character )
{
  	while (PIR1bits.TXIF == 0);	    	// Wait till Tx buffer is empty
	TXREG = character;					// Load TX buffer with the character
}

// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~// Send a string of characters ~~~~~~~~~

void
McalUart_Puts( char *string )  // Send a null terminated string of
                                          // charaters via the serial port 
                                          // "McalUart_Puts('null terminated
                                          // source string')"
{								   
   while(*string!='\0')                	// Keep sending until 'NULL' is 
                                          // encountered.
   {
    	McalUart_Putc(*string);	        // Send character by character
    	string++;			  			// Increment the pointer to string
   }
}

// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~// Send a string of characters ~~~~~~~~~

void McalUart_Putrs(const rom char *string)  // Send a null terminated string of
                                          // charaters via the serial port 
                                          // "McalUart_Puts('null terminated
                                          // source string')"
{								   
   while(*string!='\0')                	// Keep sending until 'NULL' is 
                                          // encountered.
   {
    	McalUart_Putc(*string);	        // Send character by character
    	string++;			  			// Increment the pointer to string
   }
}

// -----------------------------------------------------------------------------
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~// USART Transmit Routine ~~~~~~~~~~~~~~~
// -----------------------------------------------------------------------------

// -----------------------------------------------------------------------------
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~// USART Receive Routine ~~~~~~~~~~~~~~~~
// -----------------------------------------------------------------------------

// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~// Receive a character ~~~~~~~~~~~~~~~~~
      
unsigned char McalUart_Getc(void)
{
  while (PIR1bits.RCIF == 0);	    	// Wait till Tx buffer is empty
  return RCREG;                     	// Load the character with RX buffer
}

// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~// Receive a string of characters ~~~~~~

void McalUart_Gets( volatile uint8_t *str, unsigned int len, Std_BoolType echo )
{  
  while(len-- != 0)
    {
      *str=McalUart_Getc();

      if (*str=='\0')					// Stop accepting data if NULL character
        // is received
        break;

      else if(*str==0x1b)				// Stop accepting data if 'Esc' is pressed
        break;

      if( TRUE == echo )
        {
          McalUart_Putc( *str );
        }

      str++;							// Point to the next char space in the
      // string
    }

  *str='\0';			        		// Terminate the received string with a
  // NULL caharter
}

// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~// Receive interrupt routine ~~~~~~~~~~~


// -----------------------------------------------------------------------------
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~// USART Receive Routine ~~~~~~~~~~~~~~~~
// -----------------------------------------------------------------------------

/**@cond ***********************************************************************
 * TODO: Update all comment fields and delete this line.
 * MOD: For functions with project scope, remove 'static' keyword and declare
 * prototype in McalUart.h
 * -------------------------------------------------------------------- @endcond
 * @fn          return_type function_name(TYPE parameter1, TYPE parameter2)
 * @return      Describe the function's return value here.
 * @param       parameter1 Describe the function's 1st parameter here.
 * @param       parameter2 Describe the function's 2nd parameter here.
 * @author      avijayak
 * @date        Aug 13, 2012, 11:02:49 PM
 * @brief	Provide a brief description of the module here (Single line).
 * @details	Provide a detailed description of the module here (Multi-line).
 * @pre         Mention any preconditions required to use this function.
 * @post        Mention any postcondition required to use this function.
 * @bug         List any bugs in this module.
 * @note        List any odd modes while using this function.
 * @warning     List any warnings against using the objects of this function.
 *******************************************************************************
 */

#pragma code HIGH_INTERRUPT_VECTOR = 0x08
void goto_McalIsr_High (void)
{
  _asm goto McalIsr_High _endasm
}
#pragma code

/** End of function_name ************ Copyright (C) 2012 Afflatus Techtronics */
